package com.bao123.userinfo.service.impl;

import com.bao123.jwt.service.JwtService;
import com.bao123.redis.service.RedisStringService;
import com.bao123.userinfo.entities.Userinfo;
import com.bao123.userinfo.mapper.UserinfoMapper;
import com.bao123.userinfo.service.UserinfoService;
import com.bao123.utils.constant.GeneralResultConstant;
import com.bao123.utils.encryption.Md5Util;
import com.bao123.utils.generator.SnowFlake;
import com.bao123.utils.result.GeneralResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户信息服务类实现类
 * @author lbw
 */
@Service
public class UserinfoServiceImpl implements UserinfoService {

    @Autowired
    private UserinfoMapper userinfoMapper;
    @Autowired
    private JwtService jwtService;
    @Autowired
    private RedisStringService redisStringService;

    /**
     * 注册
     * @param userinfo 用户相关信息
     * @return 通用返回结果
     */
    @Override
    public GeneralResult<?> register(Userinfo userinfo, String verificationCode) {
        Userinfo dbUserinfo = getUserinfoByUsername(userinfo.getUsername());
        if (dbUserinfo != null){
            return new GeneralResult<>(GeneralResultConstant.FAIL,"注册失败,当前用户名已经存在");
        }
        //  获取验证码，进行验证码判断
        String key = userinfo.getEmail() + ":VerificationCode";
        String dbVerificationCode = redisStringService.getValue(key);
        if (StringUtils.isBlank(verificationCode) || !verificationCode.equals(dbVerificationCode)){
            return new GeneralResult<>(GeneralResultConstant.FAIL,"注册失败,验证码错误");
        }
        String password = userinfo.getPassword();
        try {
            userinfo.setPassword(Md5Util.encoderByMd5(password, Md5Util.USER_PASSWORD_USE));
        } catch (NoSuchAlgorithmException e) {
            //TODO 进行全局异常处理
            System.err.println("注册时对密码进行md5加密失败");
        }
        userinfo.setUserId(SnowFlake.getSnowFlakeId());
        userinfo.setCreateDate(LocalDateTime.now());
        Integer result = userinfoMapper.insertUser(userinfo);
        if (result == 1){
            return new GeneralResult<>(GeneralResultConstant.SUCCESS, "注册成功");
        }
        return new GeneralResult<>(GeneralResultConstant.FAIL,"注册失败!");
    }

    @Override
    public GeneralResult<?> login(String username, String password, HttpServletResponse response) {
        Userinfo dbUserinfo = getUserinfoByUsername(username);
        if (dbUserinfo == null){
            return new GeneralResult<>(GeneralResultConstant.FAIL,"登录失败,用户名或密码错误");
        }
        try {
            password = Md5Util.encoderByMd5(password, Md5Util.USER_PASSWORD_USE);
        } catch (NoSuchAlgorithmException e) {
            //TODO 进行全局异常处理
            System.err.println("注册时对密码进行md5加密失败");
        }
        if (!password.equals(dbUserinfo.getPassword())){
            return new GeneralResult<>(GeneralResultConstant.FAIL,"登录失败,用户名或密码错误");
        }
        Map<String, Object> userinfoMap = new HashMap<>(16);
        userinfoMap.put("username", dbUserinfo.getUsername());
        userinfoMap.put("nickname", dbUserinfo.getNickname());
        userinfoMap.put("phone", dbUserinfo.getPhone());
        String token = jwtService.generateToken(userinfoMap);
        Cookie cookie = new Cookie("token", token);
        cookie.setPath("/");
        cookie.setMaxAge(3*60*60);
        response.addCookie(cookie);
        return new GeneralResult<>(GeneralResultConstant.SUCCESS,"登录成功!", token);
    }


    //----------------------------------以下方法为接口中未定义的，只是为本类服务-----------------------------------------------

    /**
     * 根据用户名查询用户
     * @param username 用户名
     * @return 用户信息，为null时表示当前用户名不存在
     */
    private Userinfo getUserinfoByUsername(String username){
        return userinfoMapper.getUserByUsername(username);
    }
}
